home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / magazi~1 / 226 / analog.49 / life.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-10-14  |  9.8 KB  |  372 lines

  1. #include <osbind.h>
  2. #define TT 0xffff      /* A time-saver for some arrays. */
  3.  
  4. int intin[64],intout[64],contrl[12],ptsin[64],ptsout[64],c,gl_apid;
  5. int array[104*52],pxy[10],pal[16],handle,offset,i,j,*base;
  6. long ncells;           /* # of cells in the matrix. */
  7. int yoff[52];
  8. int tcolumn[52],bcolumn[52],change[52];
  9.  
  10. int palette[16] = {     /* Color definitions for "rainbow" */
  11.  0x000,0x700,0x730,0x750,0x770,0x470,0x070,0x075,0x077,0x057,0x027,
  12.  0x007,0x507,0x707,0x704,0x777 };
  13.  
  14. int curform[37] = {     /* Box cursor mouse form definition */
  15.  2,2,1,0,1,
  16.  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  17.  0xf800,0x8800,0x8800,0x8800,0xf800,0,0,0,0,0,0,0,0,0,0,0 };
  18.  
  19. /* Continue and Live tables (for faster color cycling) */
  20. int cotab[16]={0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15};
  21. int litab[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15};
  22.  
  23. /* Top and Bottom arrays for fast processing later on */
  24. int topcol[52],botcol[52];
  25.  
  26. /* Tables for fast plot routine */
  27. int bits[4]={0xe000,0x0e00,0x00e0,0x000e};
  28. int ebit[4]={0x0fff,0xf0ff,0xff0f,0xfff0};
  29. int bit0[16]={0,TT,0,TT,0,TT,0,TT,0,TT,0,TT,0,TT,0,TT};
  30. int bit1[16]={0,0,TT,TT,0,0,TT,TT,0,0,TT,TT,0,0,TT,TT};
  31. int bit2[16]={0,0,0,0,TT,TT,TT,TT,0,0,0,0,TT,TT,TT,TT};
  32. int bit3[16]={0,0,0,0,0,0,0,0,TT,TT,TT,TT,TT,TT,TT,TT};
  33.  
  34. /* Do one generation on the grid. */
  35. do_grid()
  36. {
  37.   register int x,y,xo,n,*aptr,*point;
  38.   int o,t,b,tcol,bcol,ch;
  39.   for (x=1; x<49; ++x)
  40.   {
  41.     if (change[x] == 1) /* Only scan columns that need to be checked. */
  42.     {
  43.       t=tcolumn[x]; b=bcolumn[x];
  44.       tcol=0; bcol=0; ch=0;
  45.       xo=x+52-offset;
  46.       for (y=t; y<=b; ++y)
  47.       {
  48.         aptr=&(array[x+offset-1+(y-1)*104]); /* Count neighbors... */
  49.         asm {               /* ... with a fast 68000 routine. */
  50.          move.w #0,n
  51.          move.w (aptr),D0
  52.          beq    l01
  53.          addq.w #1,n
  54.     l01: move.w 2(aptr),D0
  55.          beq    l02
  56.          addq.w #1,n
  57.     l02: move.w 4(aptr),D0
  58.          beq    l10
  59.          addq.w #1,n
  60.     l10: move.w 208(aptr),D0
  61.          beq    l12
  62.          addq.w #1,n
  63.     l12: move.w 212(aptr),D0
  64.          beq    l20
  65.          addq.w #1,n
  66.     l20: move.w 416(aptr),D0
  67.          beq    l21
  68.          addq.w #1,n
  69.     l21: move.w 418(aptr),D0
  70.          beq    l22
  71.          addq.w #1,n
  72.     l22: move.w 420(aptr),D0
  73.          beq    ldo
  74.          addq.w #1,n
  75.     ldo:
  76.         }
  77.         o=array[x+offset+yoff[y]];  /* Get old cell value. */
  78.         point=&array[xo+yoff[y]];   /* Get address of new cell value. */
  79.         if (n == 2)                 /* 2 neigbors? */
  80.           *point = cotab[o];        /*  Yes, continue present state. */
  81.         if (n == 3)                 /* 3 neighbors? */
  82.           *point = litab[o];        /*  Yes, bring to life or keep alive. */
  83.         if ((n<2) || (n>3))         /* Anything else? */
  84.           *point = 0;               /*  Yes, this cell is DEAD. */
  85.         if (*point != o)            /* Did it change? */
  86.         { if (*point && (!o))       /*  Yes, update cell count. */
  87.             ++ncells;
  88.           if (! *point)
  89.             --ncells;
  90.           ++ch;
  91.           plot(x-1,y-1,*point);     /* Plot new point. */
  92.           if (tcol == 0)            /* Update top and bottom of column. */
  93.             tcol=topcol[y];
  94.           bcol=botcol[y];
  95.         }
  96.       }
  97.       if (x > 1)
  98.       { if ((tcolumn[x-1] < tcol) && (change[x-1] == 1))
  99.           tcol=tcolumn[x-1];
  100.         if ((bcolumn[x-1] > bcol) && (change[x-1] == 1))
  101.           bcol=bcolumn[x-1];
  102.       }
  103.       if (! tcol)
  104.         ++tcol;
  105.       if (bcol>50)
  106.         --bcol;
  107.       bcolumn[x]=bcol;
  108.       tcolumn[x]=tcol;
  109.       if (tcol < tcolumn[x-1])
  110.         tcolumn[x-1]=tcol;
  111.       if (bcol > bcolumn[x-1])
  112.         bcolumn[x-1]=bcol;
  113.       if (ch != 0)
  114.       { change[x-1]=1;
  115.         change[x]=1;
  116.         change[x+1]=1;
  117.       }
  118.       else
  119.         change[x]=0;
  120.     }
  121.   }
  122. }
  123.  
  124. /* Initialize array and let user draw a pattern.  Kludgy, but it works. */
  125. edit_array()
  126. {
  127.   int x,y,mx,my,butn;
  128.   clear_rect();
  129.   v_gtext(handle,204,150,"Left button to");
  130.   v_gtext(handle,207,156,"toggle cells.");
  131.   v_gtext(handle,204,165,"Right button to");
  132.   v_gtext(handle,207,171,"begin generation.");
  133.   butn=1;
  134.   while (butn & 1)
  135.     graf_mkstate(&x,&x,&butn,&x);
  136.   v_show_c(handle,0);
  137.   butn=0;
  138.   while (! (butn & 2))   /* Wait for right button */
  139.   { graf_mkstate(&mx,&my,&butn,&x);
  140.     if (butn & 1)             /* Left button is pressed */
  141.     { int n;
  142.       x=mx/4+1; y=my/4+1;
  143.       if (x<49)               /* In the workspace? */
  144.       { n=(! array[x+offset+yoff[y]]);
  145.         changcell(x,y,n);
  146.         while (butn & 1)
  147.         { graf_mkstate(&mx,&my,&butn,&y);
  148.           changcell(mx/4+1,my/4+1,n);
  149.         }
  150.       }
  151.     }
  152.   }
  153.   while (butn&0x0002)         /* Wait for button to be released */
  154.     graf_mkstate(&mx,&my,&butn,&x);
  155. }
  156.  
  157. /* Change cell state to ON or OFF (color 1). */
  158. changcell(x,y,state)
  159. int x,y,state;
  160. {
  161.   int *st2;
  162.   if (x>48)
  163.     return(0);
  164.   st2=&array[x+offset+yoff[y]];
  165.   if ((*st2&&state)||((!*st2)&&(!state)))
  166.     return(0);
  167.   *st2=state;
  168.   v_hide_c(handle);
  169.   plot(x-1,y-1,state);
  170.   if (state)
  171.     ++ncells;
  172.   else
  173.     --ncells;
  174.   printn(270,128,ncells);
  175.   v_show_c(handle,0);
  176. }
  177.  
  178. /* Tie everything together. */
  179. main()
  180. {
  181.   int work_in[11],work_out[57],butns,key,dummy,x,y;
  182.   long gen;
  183.   appl_init();
  184.   if ((int)Getrez())
  185.   { form_alert(1,"[2][Life! requires| |LOW RESOLUTION!][Okay...]");
  186.     exit(0);
  187.   }
  188.   for (i=0; i<16; ++i)            /* Save user's colors. */
  189.     pal[i]=(int)Setcolor(i,-1);
  190.   Setpallete(palette);            /* Install rainbow colors. */
  191.   base=(int *)Physbase();         /* Get screen address. */
  192.   for (i=0; i<10; work_in[i]=1, ++i);
  193.   work_in[10]=2;
  194.   v_opnvwk(work_in,&handle,work_out);
  195.   v_hide_c(handle);
  196.   v_clrwk(handle);
  197.   vsf_interior(handle,1);
  198.   vsc_form(handle,curform);
  199.   title();
  200.   offset=0; gen=0; ncells=0;
  201.   for (x=0; x<52; ++x)
  202.   { yoff[x]=x*104;
  203.     for (y=0; y<52; ++y)
  204.     { array[x+yoff[y]]=0;
  205.       array[x+52+yoff[y]]=0;
  206.     }
  207.   }
  208.  
  209.  edit:
  210.   edit_array();
  211.  
  212.  dogens:
  213.   for (x=0; x<52; ++x)
  214.   { tcolumn[x]=1; bcolumn[x]=50;
  215.     change[x]=1;
  216.     topcol[x]=x-1; botcol[x]=x+1;
  217.   }
  218.   change[0] = 0; change[49] = 0;
  219.   topcol[1] = 1; topcol[50] = 50;
  220.   clear_rect();
  221.   v_gtext(handle,204,150,"Left button to");
  222.   v_gtext(handle,207,156,"edit cells");
  223.   v_gtext(handle,204,165,"Right button to");
  224.   v_gtext(handle,207,171,"exit program");
  225.   v_gtext(handle,204,180,"Alternate to pause");
  226.   v_hide_c(handle);
  227.   while (1)
  228.   { ++gen;
  229.     printn(270,120,gen);
  230.     printn(270,128,ncells);
  231.     do_grid();
  232.     offset = 52-offset;
  233.     graf_mkstate(&dummy,&dummy,&butns,&key);
  234.     if (butns == 1)
  235.       goto edit;
  236.     if (butns == 2)
  237.       break;
  238.     while (key==8)
  239.       graf_mkstate(&dummy,&dummy,&dummy,&key);
  240.   }
  241.   xbios(6,pal);
  242.   appl_exit();
  243.   exit(0);
  244. }
  245.  
  246. /* Plot all the junk on the right side of the screen. */
  247. title()
  248. {
  249.   vsf_color(handle,14);  /* ST color 11 */
  250.   pxy[0]=194; pxy[1]=0;
  251.   pxy[2]=194; pxy[3]=199;
  252.   pxy[4]=319; pxy[5]=199;
  253.   pxy[6]=319; pxy[7]=0;
  254.   pxy[8]=194; pxy[9]=0;
  255.   v_pline(handle,5,pxy);
  256.   vst_color(handle,9);  /* ST color 8 */
  257.   vst_height(handle,28,&i,&i,&i,&i);
  258.   vst_effects(handle,16);
  259.   v_gtext(handle,214,30,"Life!");
  260.   vst_height(handle,6,&i,&i,&i,&i);
  261.   vst_effects(handle,0);
  262.   vst_color(handle,2);   /* ST color 1 */
  263.   v_gtext(handle,208,60,"Steven Grimm");
  264.   vst_color(handle,4);  /* ST color 4 */
  265.   vst_height(handle,4,&i,&i,&i,&i);
  266.   v_gtext(handle,250,49,"by");
  267.   v_gtext(handle,207,88,"ANALOG Computing");
  268.   vst_color(handle,7);  /* ST color 5 */
  269.   v_gtext(handle,204,120,"Generation:");
  270.   v_gtext(handle,234,128,"Cells:");
  271. }
  272.  
  273. /* Clear a rectangle in the lower right corner of the screen to print
  274.    instructions. */
  275. clear_rect()
  276. {
  277.   pxy[0]=195; pxy[1]=140;
  278.   pxy[2]=318; pxy[3]=198;
  279.   vsf_color(handle,0);
  280.   vr_recfl(handle,pxy);
  281. }
  282.  
  283. /* Print generation number next to "Generation:". */
  284. printn(x,y,num)
  285. int x,y;
  286. long num;
  287. {
  288.   long i;
  289.   char c[2],pnum=0;
  290.   if (! num)                      /* Special handling for no cells */
  291.   { v_gtext(handle,x,y,"NONE");
  292.     return(0);
  293.   }
  294.   c[1]=0;
  295.   for (i=10000000; i>0; i /= 10)  /* Print one power of 10 at a time */
  296.   { if ((num/i) || (x>270))       /* Need to print a digit? */
  297.     { c[0]=(num/i)+48;            /* What do we want to print? */
  298.       v_gtext(handle,x,y,c);      /* Put the digit to the screen */
  299.       num -= (i*(num/i));         /* Subtract it from the main number */
  300.       x += 6;                     /* Move the "cursor" */
  301.       ++pnum;
  302.     }
  303.   }
  304.   c[0]=32;
  305.   while (pnum<8)                  /* Pad the rest of the space with blanks */
  306.   { ++pnum;
  307.     v_gtext(handle,x,y,c);
  308.     x += 6;
  309.   }
  310. }
  311.  
  312. /* Special plot routine. */
  313. plot(x,y,color)
  314. int x,y,color;
  315. {
  316.   static int b0,b1,b2,b3,*screen,xbit;
  317.   auto int *eptr;
  318.   screen=base;
  319.   screen += (y*320);
  320.   screen += (x & 0xfffc);
  321.   x = x & 0x0003;
  322.   xbit = bits[x];
  323.   b0 = bit0[color] & xbit;
  324.   b1 = bit1[color] & xbit;
  325.   b2 = bit2[color] & xbit;
  326.   b3 = bit3[color] & xbit;
  327.   eptr=ebit+x;
  328.   asm {
  329.     movea.l screen(A4),A1
  330.     movea.l eptr(A6),A0
  331.     move.w  (A1),D0
  332.     and.w   (A0),D0
  333.     or.w    b0(A4),D0
  334.     move.w  D0,(A1)
  335.     move.w  2(A1),D1
  336.     and.w   (A0),D1
  337.     or.w    b1(A4),D1
  338.     move.w  D1,2(A1)
  339.     move.w  4(A1),D2
  340.     and.w   (A0),D2
  341.     or.w    b2(A4),D2
  342.     move.w  D2,4(A1)
  343.     move.w  6(A1),D3
  344.     and.w   (A0),D3
  345.     or.w    b3(A4),D3
  346.     move.w  D3,6(A1)
  347.     adda.l  #160,A1
  348.     move.w  D0,(A1)
  349.     move.w  D1,2(A1)
  350.     move.w  D2,4(A1)
  351.     move.w  D3,6(A1)
  352.     adda.l  #160,A1
  353.     move.w  D0,(A1)
  354.     move.w  D1,2(A1)
  355.     move.w  D2,4(A1)
  356.     move.w  D3,6(A1)
  357.   }
  358. }
  359.  
  360. /* Null routines to trick the Megamax linker into not including the
  361.    (unnecessary) file I/O stuff */
  362. fopen()
  363. { }
  364. fclose()
  365. { }
  366. fread()
  367. { }
  368. fwrite()
  369. { }
  370. fseek()
  371. { }
  372.